﻿using System;
using System.IO;
using System.Text;
using System.Web;
using System.Web.UI;

namespace WebDotNet.Extensions
{
	public static class WebFormsExtensions
	{
		public const string ViewDataKey = "__viewData";
		public const string ThemeKey = "__theme";

		public static StringBuilder RenderPage(this HttpContextBase httpContextBase, string templateName, object viewData)
		{
			return httpContextBase.RenderPage(null, templateName, viewData);
		}

		public static StringBuilder RenderPage(this HttpContextBase httpContextBase, string themeName, string templateName, object viewData)
		{
			if (httpContextBase == null) throw new ArgumentNullException("httpContextBase");
			if (string.IsNullOrEmpty(templateName)) throw new ArgumentNullException("templateName");

			string path = getViewPath(themeName ?? (string)httpContextBase.Items[ThemeKey], templateName, true);

			httpContextBase.Items[ViewDataKey] = viewData;

			StringBuilder stringBuilder = new StringBuilder();

			using (StringWriter stringWriter = new StringWriter(stringBuilder))
			{
				using (HtmlTextWriter htmlTextWriter = new HtmlTextWriter(stringWriter))
				{
					httpContextBase.Server.Execute(path, htmlTextWriter);
					return stringBuilder;
				}
			}
		}

		public static StringBuilder RenderControl(this HttpContextBase httpContextBase, string templateName, object viewData)
		{
			return httpContextBase.RenderControl(null, templateName, viewData);
		}

		public static StringBuilder RenderControl(this HttpContextBase httpContextBase, string themeName, string templateName, object viewData)
		{
			if (httpContextBase == null) throw new ArgumentNullException("httpContextBase");
			if (string.IsNullOrEmpty(templateName)) throw new ArgumentNullException("templateName");

			string path = getViewPath(themeName ?? (string)httpContextBase.Items[ThemeKey], templateName, false);

			object tempViewData = httpContextBase.Items[ViewDataKey];
			httpContextBase.Items[ViewDataKey] = viewData;

			try
			{
				StringBuilder stringBuilder = new StringBuilder();

				using (Page page = new Page())
				{
					using (Control control = page.LoadControl(path))
					{
						page.Controls.Add(control);

						using (StringWriter stringWriter = new StringWriter(stringBuilder))
						{
							using (HtmlTextWriter htmlTextWriter = new HtmlTextWriter(stringWriter))
							{
								page.RenderControl(htmlTextWriter);
							}
						}
					}
				}

				return stringBuilder;
			}
			finally
			{
				httpContextBase.Items[ViewDataKey] = tempViewData;
			}
		}

		private static string getViewPath(string themeName, string templateName, bool page)
		{
			if (string.IsNullOrEmpty(templateName)) throw new ArgumentNullException("templateName");

			return string.Format("~/Views/{0}/{1}.{2}", themeName ?? "Default", templateName, page ? "aspx" : "ascx");
		}
	}
}
